import React, { useEffect, useState, useRef } from 'react'
import { Card, Table, Space, Button, Modal, Row, Col, Tag, Form, Input, Tree, Tooltip } from 'antd'
import type { ColumnsType } from 'antd/es/table'
import type { FormInstance } from 'antd/lib/form/Form'
import type { DataNode, TreeProps } from 'antd/es/tree'
import { EditOutlined, DeleteOutlined, SettingOutlined } from '@ant-design/icons'
import { createRole, updateRole, deleteRole, getRolesList, updateRoleRight, deleteRoleRight } from '@/service/roles'
import { getRightsList } from '@/service/rights'
import { useTranslation } from 'react-i18next'
import './index.scss'
import Pop from '@/components/pop'

export default function Roles() {
  type DataType = {
    id: number
    roleName: string
    roleDesc: string
    children: DataType[]
    expandData: DataType[]
    authName?: string
  }
  type FieldType = {
    roleName: string
    roleDesc: string
  }
  const { t } = useTranslation()
  const [dataList, setDataList] = useState<DataType[]>([])
  const [openType, setOpenType] = useState('add')
  const [addOrEditVisible, setAddOrEditVisible] = useState<boolean>(false)
  const [disRightsVisible, setDisRightsVisible] = useState<boolean>(false)
  const formRef = useRef<FormInstance>(null)
  const [rowId, setRowId] = useState(0)
  const [treeData, setTreeData] = useState<DataNode[]>([])
  const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([])
  const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([])
  const [halfCheckedKeys, setHalfCheckedKeys] = useState<React.Key[]>([])

  const columns: ColumnsType<DataType> = [
    {
      title: t('users.table.index'),
      align: 'center',
      width: 70,
      render: (text, record, index) => index + 1
    },
    {
      title: t('users.table.role_name'),
      key: 'roleName',
      dataIndex: 'roleName',
      align: 'center'
    },
    {
      title: t('users.table.role_desc'),
      key: 'roleDesc',
      dataIndex: 'roleDesc',
      align: 'center'
    },
    {
      title: t('users.table.action.title'),
      key: 'action',
      align: 'center',
      width: 300,
      render: record => (
        <div className="btns">
          <Tooltip title={t('users.table.action.edit')}>
            <Button
              type="primary"
              size="small"
              shape="circle"
              icon={<EditOutlined />}
              onClick={() => editRow(record)}
            ></Button>
          </Tooltip>

          <Pop onConfirm={() => delRow(record)}>
            <Tooltip title={t('users.table.action.del')}>
              <Button danger type="primary" shape="circle" size="small" icon={<DeleteOutlined />}></Button>
            </Tooltip>
          </Pop>
          <Tooltip title={t('users.table.action.distributeRight')}>
            <Button
              type="primary"
              size="small"
              shape="circle"
              ghost
              icon={<SettingOutlined />}
              onClick={() => openDisRights(record)}
            ></Button>
          </Tooltip>
        </div>
      )
    }
  ]

  const handleSearch = () => {
    getRolesList().then((res: any) => {
      // 注意！！！ 系统会自动渲染children,导致子数据也会成为一行数据，需要将chidren作为当前行数据的一个属性展开项
      const arr = res.data.map((item: any) => {
        return {
          id: item.id,
          roleName: item.roleName,
          roleDesc: item.roleDesc,
          expandData: item.children
        }
      })
      setDataList(arr)
    })
  }
  const openAddDialog = () => {
    setOpenType('add')
    setAddOrEditVisible(true)
  }
  const editRow = (row: DataType) => {
    setAddOrEditVisible(true)
    setOpenType('edit')
    formRef.current?.setFieldsValue({
      id: row.id,
      roleName: row.roleName,
      roleDesc: row.roleDesc
    })
  }
  const delRow = (row: DataType) => {
    console.log(row)
    // deleteRole({ id: row.id }).then(() => {
    //   handleSearch()
    // })
  }
  const getLeaveslIds = (arr: DataType, result: number[] = [], halfResult: number[] = []) => {
    // 递归获取所有叶子节点
    if (!arr.children) {
      result.push(arr.id)
    } else {
      halfResult.push(arr.id)
      arr.children.forEach((item: DataType) => getLeaveslIds(item, result, halfResult))
    }
    return {
      result,
      halfResult
    }
  }
  const openDisRights = (row: DataType) => {
    setDisRightsVisible(true)
    // 拿到选中的节点并设置
    getRightsList({ type: 'tree' }).then((res: any) => {
      setTreeData(res.data)
    })
    setRowId(row.id)
    // 设置选中的叶子节点
    const checkedArr: any = [],
      halfCheckedArr: any = []
    for (const item of row.expandData) {
      const { result, halfResult } = getLeaveslIds(item, [])
      checkedArr.push(result)
      halfCheckedArr.push(halfResult)
    }
    // 子节点用于Tree渲染选中节点效果
    setCheckedKeys(checkedArr.flat(Infinity))
    // 默认半选中节点
    setHalfCheckedKeys(halfCheckedArr.flat(Infinity))
  }
  const removeRightByID = (row: DataType, rightId: number) => {
    deleteRoleRight({ id: row.id, rightId }).then(() => {
      handleSearch()
    })
  }
  const handleAddModalOk = () => {
    formRef.current?.submit()
  }
  const handleAddModalCancel = () => {
    setAddOrEditVisible(false)
    formRef.current?.resetFields()
  }
  const onFinish = (values: any) => {
    if (openType === 'add') {
      createRole(values).then(() => {
        handleAddModalCancel()
        handleSearch()
      })
    } else {
      updateRole(values).then(() => {
        handleAddModalCancel()
        handleSearch()
      })
    }
  }
  const onFinishFailed = (errorInfo: any) => {
    console.log('Failed:', errorInfo)
  }
  const handleDistModalOk = () => {
    const endArr = new Set([...checkedKeys, ...halfCheckedKeys])
    updateRoleRight({
      id: rowId,
      rids: [...endArr].join(',')
    }).then(() => {
      handleDisModalCancel()
      handleSearch()
    })
  }
  const handleDisModalCancel = () => {
    setCheckedKeys([])
    setSelectedKeys([])
    setHalfCheckedKeys([])
    setDisRightsVisible(false)
  }
  const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
    setSelectedKeys(selectedKeys)
  }

  const onCheck: TreeProps['onCheck'] = (checkedKeys: any, info: any) => {
    // 选中节点和半选中节点的id数组
    setCheckedKeys(checkedKeys)
    setHalfCheckedKeys([...halfCheckedKeys, ...info.halfCheckedKeys])
  }
  useEffect(() => {
    handleSearch()
  }, [])
  return (
    <section className="container-wrapper">
      <Card className="card">
        <Space>
          <Button type="primary" onClick={openAddDialog}>
            {t('roles.add')}
          </Button>
        </Space>
        <Table
          style={{ marginTop: '20px' }}
          rowKey="id"
          columns={columns}
          dataSource={dataList}
          pagination={false}
          bordered
          expandable={{
            expandedRowRender: record =>
              record.expandData.map((item: DataType, i1: number) => (
                <Row key={item.id} className={['border-bottom', i1 === 0 ? 'border-top' : 'flex-center'].join(' ')}>
                  <Col span={5}>
                    <Tag color="processing" closable onClose={() => removeRightByID(record, item.id)}>
                      {item.authName + '-' + item.id}
                    </Tag>

                    {item.id && <i className="iconfont icon-caret-right"></i>}
                  </Col>
                  <Col span={19}>
                    {item.children &&
                      item.children.map((item2: DataType, i2: number) => (
                        <Row key={item2.id} className={[i2 === 0 ? 'border-top' : 'flex-center'].join(' ')}>
                          <Col span={6}>
                            <Tag color="success" closable onClose={() => removeRightByID(record, item2.id)}>
                              {item2.authName + '-' + item2.id}
                            </Tag>
                            {item2.id && <i className="iconfont icon-caret-right"></i>}
                          </Col>
                          <Col span={18}>
                            {item2.children &&
                              item2.children.map((item3: DataType) => (
                                <Tag
                                  key={item3.id}
                                  color="warning"
                                  closable
                                  onClose={() => removeRightByID(record, item3.id)}
                                >
                                  {item3.authName + '-' + item3.id}
                                </Tag>
                              ))}
                          </Col>
                        </Row>
                      ))}
                  </Col>
                </Row>
              ))
          }}
        ></Table>
        <Modal
          title={openType === 'add' ? t('roles.add') : t('roles.edit')}
          centered
          open={addOrEditVisible}
          onOk={handleAddModalOk}
          onCancel={handleAddModalCancel}
          forceRender={true}
          okText={t('modal.okText')}
          cancelText={t('modal.cancelText')}
        >
          <Form
            name="basic"
            ref={formRef}
            style={{ maxWidth: 600 }}
            labelCol={{ span: 4 }}
            initialValues={{ remember: true }}
            onFinish={onFinish}
            onFinishFailed={onFinishFailed}
            autoComplete="off"
            layout="horizontal"
          >
            {openType === 'add' ? null : (
              <Form.Item<FieldType> label={t('roles.form.id')} name="id">
                <Input disabled />
              </Form.Item>
            )}
            <Form.Item<FieldType>
              label={t('roles.form.role_name')}
              name="roleName"
              rules={[{ required: true, message: t('roles.form.required_name') }]}
            >
              <Input />
            </Form.Item>
            <Form.Item<FieldType>
              label={t('roles.form.role_desc')}
              name="roleDesc"
              rules={[{ required: true, message: t('roles.form.required_desc') }]}
            >
              <Input />
            </Form.Item>
          </Form>
        </Modal>
        <Modal
          title="分配权限"
          open={disRightsVisible}
          onOk={handleDistModalOk}
          onCancel={handleDisModalCancel}
          forceRender={true}
          okText={t('modal.okText')}
          cancelText={t('modal.cancelText')}
        >
          <Tree
            checkable
            treeData={treeData}
            onCheck={onCheck}
            onSelect={onSelect}
            checkedKeys={checkedKeys}
            selectedKeys={selectedKeys}
            multiple
          ></Tree>
        </Modal>
      </Card>
    </section>
  )
}
